#ifndef VM_H
#define VM_H


#include <stdio.h>
#include "semaphore.h"
#include "queue.h"


/*define our word size*/
typedef char word[5];

/*Struct that represents a brain10 virtual machine.*/
typedef struct brain10_t{
	word memory[10000];
	word shared[100];            /* added in project 3 */
	semaphore semaphores[100];   /* added in project 3 */
	char R[5];  // register
	char IC[3]; // counter
	char SP[5]; // stack pointer
	char BR[5]; // base register
	char LR[5]; // limit register
	char C;     // bool
	char PID[3]; // process id
}brain10;

/*print the contents of the vm*/
void print(brain10 *vm);

void initSemaphores(brain10* vm, int value);

/* this function needs to be called in order to use
 * semaphores. It tells the semaphores which ready queue
 * they are receiving waits and signals from, and where
 * processes should be placed when they are removed from a
 * semaphore queue.
 */
void setReadyQ(list* readyQ); /* added in project 3 */

/*calculates the BR of the next process
 * based on the current amount of instructions
 * read.
 */
int calcBR(int current);

/*saves vm state to a process control block*/
void storeContext(pcb* block, brain10* vm);
void loadContext(brain10* vm, pcb* block);
void reset(brain10* vm);

/*Load a program into the vm*/
FILE* loadProgram(brain10 *vm, char fileName[], list* rdyQ);

void LR(brain10 *vm, int address);//done
void LL(brain10 *vm, int address);//done
void LH(brain10 *vm, int address);//done
void SR(brain10 *vm, int address);//done


void SP(brain10 *vm);//done
void PS(brain10 *vm);//done
void PH(brain10 *vm);//done
void PP(brain10 *vm);//done

void CE(brain10 *vm, int address);//done
void CL(brain10 *vm, int address);//done
int BT(brain10 *vm, char arg[]);//done
void BU(brain10 *vm, char arg[]);//done

void GD(brain10 *vm, int address, FILE *file); //done
void PD(brain10 *vm, int start); //done
void AD(brain10 *vm, int address); //done
void SU(brain10 *vm, int address); //done
void MU(brain10 *vm, int address); //done
void DI(brain10 *vm, int address); //done

void AS(brain10 *vm); //done
void SS(brain10 *vm); //done
void MS(brain10 *vm); //done
void DS(brain10 *vm); //done

/* project 2 */
int SD(brain10* vm, list* sndQ, list* rcvQ, list* rdyQ, char* targetPID);
int RC(brain10* vm, list* sndQ, list* rcvQ, list* rdyQ, char* targetPID);
void GP(brain10 *vm);

/* project 3 */
void LS(brain10* vm, int address);
void ST(brain10* vm, int address);
int PE(brain10* vm, int address);
int VE(brain10* vm, int address);
void SI(brain10* vm, int address);



#endif

